home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / gsdbloo.exe / GS_OBJTS.PAS < prev    next >
Pascal/Delphi Source File  |  1992-02-20  |  9KB  |  370 lines

  1. unit GS_Objts;
  2. {-----------------------------------------------------------------------------
  3.                             Collection Handler
  4.  
  5.        GS_Objts Copyright (c)  Richard F. Griffin
  6.  
  7.        14 September 1991
  8.  
  9.        102 Molded Stone Pl
  10.        Warner Robins, GA  31088
  11.  
  12.        -------------------------------------------------------------
  13.        This unit handles the objects for collections.  This is an
  14.        abbreviated version of the Borland TP6 Objects unit.  It is
  15.        intended as a substitute for use in TP5.5.
  16.  
  17.        Changes:
  18.  
  19. ------------------------------------------------------------------------------}
  20.  
  21. {$D-}
  22.  
  23. interface
  24.  
  25. const
  26.  
  27.    MaxCollectionSize = 65520 div SizeOf(Pointer);
  28.  
  29.    coIndexError = -1;            { Index out of range }
  30.    coOverflow   = -2;            { Overflow }
  31.  
  32.    coCollError  = 212;
  33.    coAbstrError = 211;
  34.  
  35. type
  36.  
  37.    PString = ^String;
  38.  
  39.    PObject = ^TObject;
  40.    TObject = object
  41.       constructor Init;
  42.       procedure   Free;
  43.       destructor  Done; virtual;
  44.    end;
  45.  
  46.    PColPntrs = ^TColPntrs;
  47.    TColPntrs = array[0..MaxCollectionSize - 1] of Pointer;
  48.  
  49.  
  50.    PCollection = ^TCollection;
  51.    TCollection = object(TObject)
  52.       Items       : PColPntrs;
  53.       Count       : Integer;
  54.       Limit       : Integer;
  55.       Delta       : Integer;
  56.       constructor Init(ALimit, ADelta: Integer);
  57.       destructor  Done; virtual;
  58.       function    At(Index: Integer): Pointer;
  59.       procedure   AtDelete(Index: Integer);
  60.       procedure   AtInsert(Index: Integer; Item: Pointer);
  61.       procedure   AtPut(Index: Integer; Item: Pointer);
  62.       procedure   Delete(Item: Pointer);
  63.       procedure   DeleteAll;
  64.       procedure   Error(Code, Info: Integer); virtual;
  65.       procedure   Free(Item: Pointer);
  66.       procedure   FreeAll;
  67.       procedure   FreeItem(Item: Pointer); virtual;
  68.       function    IndexOf(Item: Pointer): Integer; virtual;
  69.       procedure   Insert(Item: Pointer); virtual;
  70.       procedure   SetLimit(ALimit: Integer); virtual;
  71.    end;
  72.  
  73.    PSortedCollection = ^TSortedCollection;
  74.    TSortedCollection = object(TCollection)
  75.       Duplicates  : Boolean;
  76.       constructor Init(ALimit, ADelta: Integer);
  77.       function    Compare(Key1, Key2: Pointer): Integer; virtual;
  78.       function    IndexOf(Item: Pointer): Integer; virtual;
  79.       procedure   Insert(Item: Pointer); virtual;
  80.       function    KeyOf(Item: Pointer): Pointer; virtual;
  81.       function    Search(Key: Pointer; var Index: Integer): Boolean; virtual;
  82.    end;
  83.  
  84.    PStringCollection = ^TStringCollection;
  85.    TStringCollection = object(TSortedCollection)
  86.       function    Compare(Key1, Key2: Pointer): Integer; virtual;
  87.       procedure   FreeItem(Item: Pointer); virtual;
  88.    end;
  89.  
  90.  
  91. procedure DisposeStr(p: PString);
  92. function NewStr(S: String): PString;
  93.  
  94. implementation
  95.  
  96. {------------------------------------------------------------------------------
  97.                              Global Procedures/Functions
  98. ------------------------------------------------------------------------------}
  99.  
  100. procedure Abstract;
  101. begin
  102.   RunError(coAbstrError);
  103. end;
  104.  
  105. procedure DisposeStr(p: PString);
  106. begin
  107.   if P <> nil then FreeMem(p, Length(p^) + 1);
  108. end;
  109.  
  110. function NewStr(S: String): PString;
  111. var
  112.   p: PString;
  113. begin
  114.   if s = '' then p := nil else
  115.   begin
  116.     GetMem(p, Length(s) + 1);
  117.     p^ := s;
  118.   end;
  119.   NewStr := p;
  120. end;
  121.  
  122. {------------------------------------------------------------------------------
  123.                                   TObject
  124. ------------------------------------------------------------------------------}
  125.  
  126. constructor TObject.Init;
  127. begin
  128. end;
  129.  
  130. procedure TObject.Free;
  131. begin
  132.    Dispose(PObject(@Self), Done);
  133. end;
  134.  
  135. destructor TObject.Done;
  136. begin
  137. end;
  138.  
  139.  
  140. {------------------------------------------------------------------------------
  141.                                   TCollection
  142. ------------------------------------------------------------------------------}
  143.  
  144. constructor TCollection.Init(ALimit, ADelta: Integer);
  145. begin
  146.    TObject.Init;
  147.    Items := nil;
  148.    Count := 0;
  149.    Limit := 0;
  150.    Delta := ADelta;
  151.    SetLimit(ALimit);
  152. end;
  153.  
  154. destructor TCollection.Done;
  155. begin
  156.    FreeAll;
  157.    SetLimit(0);
  158. end;
  159.  
  160. function TCollection.At(Index: Integer): Pointer;
  161. begin
  162.    if (Index < 0) or (Index >= Count) then
  163.    begin
  164.       Error(coCollError, coIndexError);
  165.       At := nil;
  166.    end
  167.       else At := Items^[Index];
  168. end;
  169.  
  170. procedure TCollection.AtDelete(Index: Integer);
  171. begin
  172.    if (Index >= 0) and (Index < Count) then
  173.    begin
  174.       if Index < Count-1 then
  175.          move(Items^[Index+1],Items^[Index],((Count-1)-Index)*4);
  176.       dec(Count);
  177.    end
  178.    else Error(coCollError, coIndexError);
  179. end;
  180.  
  181. procedure TCollection.AtInsert(Index: Integer; Item: Pointer);
  182. begin
  183.    if (Index >= 0) and (Index <= Count) then
  184.    begin
  185.       if Count = Limit then SetLimit(Limit+Delta);
  186.       if Index <> Count then
  187.          move(Items^[Index],Items^[Index+1],(Count-Index)*4);
  188.       Items^[Index] := Item;
  189.       inc(Count);
  190.    end
  191.    else Error(coCollError, coIndexError);
  192. end;
  193.  
  194. procedure TCollection.AtPut(Index: Integer; Item: Pointer);
  195. begin
  196.    if (Index >= 0) and (Index <= Count) then
  197.       Items^[Index] := Item
  198.    else Error(coCollError, coIndexError);
  199. end;
  200.  
  201. procedure TCollection.Delete(Item: Pointer);
  202. begin
  203.    AtDelete(IndexOf(Item));
  204. end;
  205.  
  206. procedure TCollection.DeleteAll;
  207. begin
  208.    Count := 0;
  209. end;
  210.  
  211. procedure TCollection.Error(Code, Info: Integer);
  212. begin
  213.    RunError(Code);
  214. end;
  215.  
  216. procedure TCollection.Free(Item: Pointer);
  217. begin
  218.    Delete(Item);
  219.    FreeItem(Item);
  220. end;
  221.  
  222. procedure TCollection.FreeAll;
  223. var
  224.   I: Integer;
  225. begin
  226.    for I := 0 to Count - 1 do FreeItem(At(I));
  227.    Count := 0;
  228. end;
  229.  
  230. procedure TCollection.FreeItem(Item: Pointer);
  231. begin
  232.    if Item <> nil then Dispose(PObject(Item), Done);
  233. end;
  234.  
  235. function TCollection.IndexOf(Item: Pointer): Integer;
  236. var
  237.    i          : integer;
  238.    foundit    : boolean;
  239. begin
  240.    foundit := false;
  241.    i := 0;
  242.    while not foundit and (i < Count) do
  243.    begin
  244.       foundit := Item = Items^[i];
  245.       if not foundit then inc(i);
  246.    end;
  247.    if foundit then IndexOf := i else IndexOf := -1;
  248. end;
  249.  
  250. procedure TCollection.Insert(Item: Pointer);
  251. begin
  252.    AtInsert(Count, Item);
  253. end;
  254.  
  255. procedure TCollection.SetLimit(ALimit: Integer);
  256. var
  257.    AItems: PColPntrs;
  258. begin
  259.    if ALimit < Count then ALimit := Count;
  260.    if ALimit > MaxCollectionSize then ALimit := MaxCollectionSize;
  261.    if ALimit <> Limit then
  262.    begin
  263.       if ALimit = 0 then AItems := nil else
  264.       begin
  265.          GetMem(AItems, ALimit * SizeOf(Pointer));
  266.          if (Count <> 0) and (Items <> nil) then
  267.             Move(Items^, AItems^, Count * SizeOf(Pointer));
  268.       end;
  269.       if Limit <> 0 then FreeMem(Items, Limit * SizeOf(Pointer));
  270.       Items := AItems;
  271.       Limit := ALimit;
  272.    end;
  273. end;
  274.  
  275. {------------------------------------------------------------------------------
  276.                                TSortedCollection
  277. ------------------------------------------------------------------------------}
  278.  
  279. constructor TSortedCollection.Init(ALimit, ADelta: Integer);
  280. begin
  281.    TCollection.Init(ALimit, ADelta);
  282.    Duplicates := False;
  283. end;
  284.  
  285. function TSortedCollection.Compare(Key1, Key2: Pointer): Integer;
  286. begin
  287.    Abstract;
  288. end;
  289.  
  290. function TSortedCollection.IndexOf(Item: Pointer): Integer;
  291. var
  292.    I: Integer;
  293. begin
  294.    IndexOf := -1;
  295.    if Search(KeyOf(Item), I) then
  296.    begin
  297.       if Duplicates then
  298.          while (I < Count) and (Item <> Items^[I]) do Inc(I);
  299.       if I < Count then IndexOf := I;
  300.    end;
  301. end;
  302.  
  303. procedure TSortedCollection.Insert(Item: Pointer);
  304. var
  305.    I: Integer;
  306. begin
  307.    if not Search(KeyOf(Item), I) or Duplicates then AtInsert(I, Item);
  308. end;
  309.  
  310. function TSortedCollection.KeyOf(Item: Pointer): Pointer;
  311. begin
  312.    KeyOf := Item;
  313. end;
  314.  
  315. function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean;
  316. var
  317.    L, H, I, C: Integer;
  318. begin
  319.    Search := False;
  320.    L := 0;
  321.    H := Count - 1;
  322.    while L <= H do
  323.    begin
  324.       I :=